package org.example.ServletServer.Connector;


import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.ServletServer.Engine.Filter.HelloFilter;
import org.example.ServletServer.Engine.Filter.LogFilter;
import org.example.ServletServer.Engine.HttpServletResponseImplement;
import org.example.ServletServer.Engine.Listener.*;
import org.example.ServletServer.Engine.Servlet.HelloServlet;
import org.example.ServletServer.Engine.Servlet.IndexServlet;
import org.example.ServletServer.Engine.Servlet.LoginServlet;
import org.example.ServletServer.Engine.Servlet.LogoutServlet;
import org.example.ServletServer.Engine.ServletContextImplement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.example.ServletServer.Engine.HttpServletRequestImplement;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.EventListener;
import java.util.List;

public class Connector implements HttpHandler,AutoCloseable {

    final Logger logger = LoggerFactory.getLogger(getClass());
    final HttpServer httpServer;
    final Duration stopDelay = Duration.ofSeconds(5);
    final ServletContextImplement servletContextImplement;

    final String host;
    final int port;
    public Connector(String host, int port) throws IOException {
        servletContextImplement = new ServletContextImplement();
        servletContextImplement.initServlet(List.of(IndexServlet.class, LoginServlet.class, LogoutServlet.class));
        servletContextImplement.initFilter(List.of(HelloFilter.class, LogFilter.class));
        List<Class<? extends EventListener>> listenerClasses = List.of(HelloHttpSessionAttributeListener.class, HelloHttpSessionListener.class,
                HelloServletContextAttributeListener.class, HelloServletContextListener.class, HelloServletRequestAttributeListener.class,
                HelloServletRequestListener.class);
        for (Class<? extends EventListener> listenerClass : listenerClasses) {
            this.servletContextImplement.addListener(listenerClass);
        }
        this.host = host;
        this.port = port;
        this.httpServer = HttpServer.create(new InetSocketAddress("0.0.0.0", 8087), 0, "/", this);
        this.httpServer.start();
        logger.info("start V2 http server at {}:{}", host, port);
    }

    @Override
    public void close() {
        if(httpServer != null) {
            this.httpServer.stop((int) this.stopDelay.toSeconds());
        }
    }


    @Override
    public void handle(HttpExchange exchange) throws IOException {
        logger.info("{}: {}?{}", exchange.getRequestMethod(), exchange.getRequestURI().getPath(), exchange.getRequestURI().getRawQuery());
        HttpServletResponseImplement httpServletResponseImplement = new HttpServletResponseImplement(exchange);
        HttpServletRequestImplement httpServletRequestImp = new HttpServletRequestImplement(exchange,servletContextImplement,httpServletResponseImplement);
        try {
            servletContextImplement.process(httpServletRequestImp,httpServletResponseImplement);
            // process(httpServletRequestImp, httpServletResponseImplement);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            httpServletResponseImplement.cleanup();
        }
    }
}
